"""
@Author  : 康帅
@Time    : 2021/3/11 9:50
@Function: 状态模式(行为模式)
@Description: 状态模式是说一个对象在其内部发生改变时，
其表现的行为和外在属性不一样，这个对象看上去就像改变了它的类型一样。
"""

# 引入ABCMeta，abstractmethod来定义抽象类和抽象方法
from abc import ABCMeta, abstractmethod


# Water 水类
# 水的状态： SolidState(固态状态) LiquidState(液体状态) GaseousState(气态)


class Water:
    """ 水(H2O)"""

    def __init__(self, state):
        self.__temperature = 25
        self.__state = state

    def set_state(self, state):
        """ 设置状态 """

        self.__state = state

    def change_state(self, state):
        """ 状态转变 """

        if self.__state:
            print("由", self.__state.get_name(), "变为", state.get_name())
        else:
            print("初始值为", state.get_name())
        self.__state = state

    def get_temperature(self):
        """ 获取温度 """

        return self.__temperature

    def set_temperature(self, temperature):
        """ 设置温度 """

        self.__temperature = temperature
        if self.__temperature <= 0:
            self.change_state(SolidState("固态"))
        elif self.__temperature <= 100:
            self.change_state(LiquidState("液态"))
        else:
            self.change_state(GaseousState("气态"))

    def rise_temperature(self, step):
        """ 温度上升 """

        self.set_temperature(self.__temperature + step)

    def reduce_temperature(self, step):
        """ 温度下降 """

        self.set_temperature(self.__temperature - step)

    def behavior(self):
        """ 不同的行为状态 """

        self.__state.behavior(self)


class State(metaclass=ABCMeta):
    """ 状态 """

    def __init__(self, name):
        self.__name = name

    def get_name(self):
        return self.__name

    @abstractmethod
    def behavior(self, waters):
        """ 不同的行为状态 """
        pass


class SolidState(State):
    """ 固态状态 """

    def __init__(self, name):
        super().__init__(name)

    def behavior(self, waters):
        """ 不同的行为状态 """
        print("我是固态，当前温度：" + str(waters.get_temperature()) + "℃")


class LiquidState(State):
    """ 液态状态 """

    def __init__(self, name):
        super().__init__(name)

    def behavior(self, waters):
        """ 不同的行为状态 """
        print("我是液态，当前温度：" + str(waters.get_temperature()) + "℃")


class GaseousState(State):
    """ 气态状态 """

    def __init__(self, name):
        super().__init__(name)

    def behavior(self, waters):
        """ 不同的行为状态 """
        print("我是气态，当前温度：" + str(waters.get_temperature()) + "℃")


if __name__ == '__main__':
    water = Water(LiquidState("液态"))
    water.behavior()
    water.set_temperature(-4)
    water.behavior()
    water.rise_temperature(18)
    water.behavior()
    water.rise_temperature(110)
    water.behavior()
